home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / pinfocom_3_0.lha / Source / support.c < prev    next >
C/C++ Source or Header  |  1992-10-26  |  7KB  |  331 lines

  1. /* support.c
  2.  *
  3.  *  ``pinfocom'' -- a portable Infocom Inc. data file interpreter.
  4.  *  Copyright (C) 1987-1992  InfoTaskForce
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; see the file COPYING.  If not, write to the
  18.  *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * $Header: /usr/opt/contrib/infocom/info/RCS/support.c,v 3.0 1992/10/21 16:56:19 pds Stab pds $
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <ctype.h>
  27. #ifndef NO_SIGNALS
  28. #include <signal.h>
  29. #endif
  30.  
  31. #include "infocom.h"
  32. #include "patchlevel.h"
  33.  
  34. ptr_t
  35. xmalloc A1(unsigned int, len)
  36. {
  37. #ifndef malloc
  38.     extern ptr_t malloc();
  39. #endif
  40.     ptr_t p;
  41.  
  42.     if ((p = malloc(len)) == NULL)
  43.     {
  44.         extern void exit P((int));
  45.  
  46.         fprintf(stderr, "xmalloc(%ud): Out of memory!\n", len);
  47.         exit(1);
  48.     }
  49.  
  50.     return (p);
  51. }
  52.  
  53. ptr_t
  54. xrealloc A2(ptr_t, p, unsigned int, len)
  55. {
  56. #ifndef realloc
  57.     extern ptr_t realloc();
  58. #endif
  59.  
  60.     if ((p = realloc(p, len)) == NULL)
  61.     {
  62.         extern void exit P((int));
  63.  
  64.         fprintf(stderr, "xrealloc(%ud): Out of memory!\n", len);
  65.         exit(1);
  66.     }
  67.  
  68.     return (p);
  69. }
  70.  
  71. void
  72. null()
  73. {
  74.     /* The NULL function */
  75. }
  76.  
  77. void
  78. change_status()
  79. {
  80.     extern header_t     data_head;
  81.     extern print_buf_t  *pbf_p;
  82.     extern word         save_blocks;
  83.     extern word         pc_page;
  84.     extern word         pc_offset;
  85.     extern word         *stack_base;
  86.     extern word         *stack_var_ptr;
  87.     extern word         *stack;
  88.     extern byte         *base_ptr;
  89.  
  90.     if (gflags.game_state == RESTART_GAME)
  91.         load_page(0, save_blocks, base_ptr);
  92.  
  93.     stack_var_ptr = stack_base;
  94.     stack = --stack_var_ptr;
  95.  
  96.     pbf_p->len = 0;
  97.  
  98.     /*
  99.      * OK, now *this* is an inane C compiler bug: Aztec C owners, rise
  100.      * up and complain!  The Aztec C compiler doesn't properly
  101.      * interpret the operation:
  102.      *          foo = bar % 0x200
  103.      * if both foo and bar are short unsigned int (16 bits) and bar
  104.      * has a value with the high bit set (i.e., 0x8000 or more).
  105.      *
  106.      * To work around it, we store the short unsigned into a long
  107.      * int and perform the operation like that.  What a pain.
  108.      */
  109. #ifdef AZTEC_C_BUG
  110.     {
  111.         long_word offset;
  112.  
  113.         pc_page = offset = data_head.game_o / BLOCK_SIZE;
  114.         pc_offset = offset = data_head.game_o % BLOCK_SIZE;
  115.     }
  116. #else
  117.     pc_page = data_head.game_o / BLOCK_SIZE;
  118.     pc_offset = data_head.game_o % BLOCK_SIZE;
  119. #endif
  120.     fix_pc();
  121.  
  122.     gflags.game_state = PLAY_GAME;
  123. }
  124.  
  125. void
  126. restart()
  127. {
  128.     Bool scripting;
  129.  
  130.     scripting = F2_IS_SET(B_SCRIPTING);
  131.  
  132.     new_line();
  133.     gflags.game_state = RESTART_GAME;
  134.     change_status();
  135.  
  136.     if (scripting)
  137.         F2_SETB(B_SCRIPTING);
  138.     else
  139.         F2_RESETB(B_SCRIPTING);
  140. }
  141.  
  142. void
  143. quit()
  144. {
  145.     extern void exit P((int));
  146.  
  147.     if (gflags.game_state == NOT_INIT)
  148.         exit(1);
  149.  
  150.     gflags.game_state = QUIT_GAME;
  151.     scr_putline("");
  152.     close_file();
  153. }
  154.  
  155. Bool
  156. do_verify()
  157. {
  158.     extern word     resident_blocks;
  159.     extern header_t data_head;
  160.     extern file_t   file_info;
  161.  
  162.     word            page;
  163.     word            offset;
  164.     word            sum;
  165.     word            save_b;
  166.  
  167.     save_b = resident_blocks;
  168.     resident_blocks = 0;
  169.  
  170.     page = 0;
  171.     offset = sizeof(header_t);
  172.     sum = 0;
  173.     while ((page < file_info.pages) || (offset < file_info.offset))
  174.         sum += get_byte(&page, &offset);
  175.  
  176.     resident_blocks = save_b;
  177.  
  178.     return (sum == data_head.verify_checksum);
  179. }
  180.  
  181. void
  182. verify()
  183. {
  184.     char            buf[81];
  185.  
  186.     sprintf(buf,
  187.             "Portable Infocom Datafile Interpreter:  Version %d.%d",
  188.             VERSION, PATCHLEVEL);
  189.     scr_putline(buf);
  190.  
  191.     ret_value(do_verify());
  192. }
  193.  
  194. void
  195. store A1(word, value)
  196. {
  197.     extern word     *stack;
  198.  
  199.     word            var;
  200.  
  201.     NEXT_BYTE(var);
  202.     if (var == 0)
  203.         *(--stack) = value;
  204.     else
  205.         put_var(var, value);
  206. }
  207.  
  208. void
  209. ret_value A1(word, result)
  210. {
  211.     extern word     pc_offset;
  212.  
  213.     word    branch;
  214.  
  215.     NEXT_BYTE(branch);
  216.  
  217.     /* Test bit 7 */
  218.     if ((branch & 0x80) != 0)
  219.     {
  220.         /* Clear bit 7 */
  221.         branch &= 0x7F;
  222.         ++result;
  223.     }
  224.  
  225.     /* Test bit 6 */
  226.     if ((branch & 0x40) == 0)
  227.     {
  228.         byte b;
  229.  
  230.         NEXT_BYTE(b);
  231.         branch = (branch << 8) + b;
  232.         /* Test bit D. If set, make branch negative. */
  233.         if (branch & 0x2000)
  234.             branch |= 0xC000;
  235.     }
  236.     else
  237.         /* Clear bit 6 */
  238.         branch &= 0xBF;
  239.  
  240.     if ((--result) != 0)
  241.     {
  242.         switch (branch)
  243.         {
  244.             case 0 :    rtn(0);
  245.                         break;
  246.             case 1 :    rtn(1);
  247.                         break;
  248.             default :   pc_offset += (branch - 2);
  249.                         fix_pc();
  250.         }
  251.     }
  252. }
  253.  
  254. byte
  255. get_byte A2(word*, page, word*, offset)
  256. {
  257.     extern word     resident_blocks;
  258.     extern byte     *base_ptr;
  259.  
  260.     byte            *ptr;
  261.  
  262.     if (*page < resident_blocks)
  263.         ptr = base_ptr + ((long_word)*page * BLOCK_SIZE) + *offset;
  264.     else
  265.         ptr = fetch_page(*page) + *offset;
  266.  
  267.     ++(*offset);
  268.     if (*offset == BLOCK_SIZE)
  269.     {
  270.         *offset = 0;
  271.         ++(*page);
  272.     }
  273.  
  274.     return (Z_TO_BYTE(ptr));
  275. }
  276.  
  277. word
  278. get_word A2(word*, page, word*, offset)
  279. {
  280.     word    temp;
  281.  
  282.     temp = get_byte(page, offset) << 8;
  283.     return ((word)(temp + get_byte(page, offset)));
  284. }
  285.  
  286. word
  287. next_word()
  288. {
  289.     word    temp;
  290.     byte    b;
  291.  
  292.     NEXT_BYTE(b);
  293.     temp = b << 8;
  294.     NEXT_BYTE(b);
  295.     return ((word)(temp + b));
  296. }
  297.  
  298. void
  299. error A2(const char *, buffer, int, value)
  300. {
  301.     char    buf[81];
  302.  
  303.     sprintf(buf, buffer, value);
  304.     scr_putmesg(buf, 1);
  305.     quit();
  306. }
  307.  
  308. void
  309. askq A1(int, sig)
  310. {
  311.     char    cmd[256];
  312.  
  313.     scr_getline( "\nDo you really want to quit (y/n) [n] ? ",
  314.                  256,
  315.                  cmd );
  316.  
  317.     if ((*cmd == 'Y') || (*cmd == 'y'))
  318.     {
  319.         extern void exit P((int));
  320.  
  321.         quit();
  322.         scr_end();
  323.         exit(0);
  324.     }
  325.  
  326.     setbuf(stdin, NULL);
  327. #ifndef NO_SIGNALS
  328.     signal(SIGINT, askq);
  329. #endif
  330. }
  331.